package com.touch.core.avatar;

import java.io.File;

import com.touch.core.Constants;
import com.touch.core.AccountConstants;
import com.touch.core.script.ByteArray;
import com.touch.core.script.ByteDecoder;
import com.touch.core.util.IOTools;

public class Avatar extends ByteDecoder implements Cloneable
{
	public String accName;
	public int charIndex;
	
	public String name = "Unused";
	public String guild = "null";
	public byte gender;
	public int sprite;
	public String Class;
	
	public int level;
	public int exp;
	public byte access;
	public byte pk;
	
	public int hp, maxHP;
	public int mp, maxMP;
	public int sp, maxSP;
	
	public int STR;
	public int DEX;
	public int INT;
	public int SPT;
	public int wDefence;
	public int mDefence;
	public int speed;	
	public byte sPoints;
	public byte aPoints;
	
	public int map;
	public int x, y, z;
	public byte direction;
	
	public String target;

	private Avatar(){}
	public Avatar(ByteArray data)
	{
		super.decode(data);
	}
	private void encodeName(ByteArray data)
	{
		data.appendTo(Constants.com_START);
		data.appendTo(AvatarCode.NAME.getValue());
		data.appendTo(name);
		data.appendTo(Constants.com_END);
	}
	private void parseName(ByteArray data)
	{
		this.name = data.toString();
	}
	private void encodeGuild(ByteArray data)
	{
		data.appendTo(Constants.com_START);
		data.appendTo(AvatarCode.GUILD.getValue());
		data.appendTo(guild);
		data.appendTo(Constants.com_END);
	}
	private void parseGuild(ByteArray data)
	{
		this.guild = data.toString();
	}
	private void encodeGender(ByteArray data)
	{
		data.appendTo(Constants.com_START);
		data.appendTo(AvatarCode.GENDER.getValue());
		data.appendTo(gender);
		data.appendTo(Constants.com_END);
	}
	private void parseGender(ByteArray data)
	{
		this.gender = data.toByte();
	}
	private void encodeStats(ByteArray data)
	{
		data.appendTo(Constants.com_START);
		data.appendTo(AvatarCode.STATS.getValue());
		data.appendTo(sprite);
		data.appendTo(level);
		data.appendTo(exp);
		data.appendTo(access);
		data.appendTo(pk);
		data.appendTo(hp);
		data.appendTo(maxHP);
		data.appendTo(mp);
		data.appendTo(maxMP);
		data.appendTo(sp);
		data.appendTo(maxSP);
		data.appendTo(STR);
		data.appendTo(DEX);
		data.appendTo(INT);
		data.appendTo(SPT);
		data.appendTo(wDefence);
		data.appendTo(mDefence);
		data.appendTo(speed);
		data.appendTo(sPoints);
		data.appendTo(aPoints);
		data.appendTo(Constants.com_END);
	}
	private void parseStats(ByteArray data)
	{		
		this.sprite = data.subArray(0, 4).toInt();
		this.level 	= data.subArray(4, 8).toInt();
		this.exp	= data.subArray(8, 12).toInt();
		this.access = data.subArray(12, 13).toByte();
		this.pk		= data.subArray(13, 14).toByte();
		this.hp		= data.subArray(14, 18).toInt();
		this.maxHP	= data.subArray(18, 22).toInt();
		this.mp		= data.subArray(22, 26).toInt();
		this.maxMP	= data.subArray(26, 30).toInt();
		this.sp		= data.subArray(30, 34).toInt();
		this.maxSP	= data.subArray(34, 38).toInt();
		this.STR 	= data.subArray(38, 42).toInt();
		this.DEX	= data.subArray(42, 46).toInt();
		this.INT	= data.subArray(46, 50).toInt();
		this.SPT	= data.subArray(50, 54).toInt();
		this.wDefence = data.subArray(54, 58).toInt();
		this.mDefence = data.subArray(58, 62).toInt();
		this.speed	= data.subArray(62, 66).toInt();
		this.sPoints= data.subArray(66, 67).toByte();
		this.aPoints= data.subArray(67, 68).toByte();
	}
	private void encodeLocation(ByteArray data)
	{
		data.appendTo(Constants.com_START);
		data.appendTo(AvatarCode.LOCATION.getValue());
		data.appendTo(map);
		data.appendTo(x);
		data.appendTo(y);
		data.appendTo(z);
		data.appendTo(direction);
	}
	private void parseLocation(ByteArray data)
	{
		this.map = data.subArray(0, 4).toInt();
		this.x	 = data.subArray(4, 8).toInt();
		this.y	 = data.subArray(8, 12).toInt();
		this.z	 = data.subArray(12, 16).toInt();
	}
	public static Avatar loadAvatar(String accName, int charnum)
	{		
		File avatarDat = new File(getDataPath(accName, charnum));
		if(!avatarDat.exists())
		{
			Avatar avatar = new Avatar();
			avatar.accName = accName;
			avatar.charIndex = charnum;
			avatar.save();
			return avatar;
		}
		
		final Avatar avatar = new Avatar();
		byte[] data = IOTools.readFileAsBytes(getDataPath(accName, charnum));
		avatar.decode(data);
		
		return avatar;		
	}	
	
	public void save()
	{
		ByteArray data = new ByteArray();
		encodeName(data);
		encodeGuild(data);
		encodeGender(data);
		encodeStats(data);
		encodeLocation(data);
		IOTools.writeBytesToFile(getDataPath(accName, charIndex), data.toArray());
	}
	public static String getDataPath(String name, int charIndex)
	{
		return AccountConstants.ACCOUNT_DIR + name + "/char" + charIndex + ".dat";
	}	
	@Override
	public void parser(ByteArray command) 
	{	
		AvatarCode code = AvatarCode.getAvatarCode(command.toArray()[0]);
		command = command.subArray(1, command.length());
		
		if(code == AvatarCode.GENDER)
			parseGender(command);
		else if(code == AvatarCode.GUILD)
			parseGuild(command);
		else if(code == AvatarCode.LOCATION)
			parseLocation(command);
		else if(code == AvatarCode.NAME)
			parseName(command);
		else if(code == AvatarCode.STATS)
			parseStats(command);		
	}
	public Avatar clone()
	{
		final Avatar clone = new Avatar();
		
		clone.access = this.access;
		clone.accName = this.accName;
		clone.aPoints = this.aPoints;
		clone.charIndex = this.charIndex;
		clone.Class = this.Class;
		clone.DEX = this.DEX;
		clone.direction = this.direction;
		clone.exp = this.exp;
		clone.guild = this.guild;
		clone.hp = this.hp;
		clone.INT = this.INT;
		clone.level = this.level;
		clone.map = this.map;
		clone.maxHP = this.maxHP;
		clone.maxMP = this.maxMP;
		clone.maxSP = this.maxSP;
		clone.mDefence = this.mDefence;
		clone.mp = this.mp;
		clone.name = this.name;
		clone.pk = this.pk;
		clone.sp = this.sp;
		clone.speed = this.speed;
		clone.sPoints = this.sPoints;
		clone.sprite = this.sprite;
		clone.SPT = this.SPT;
		clone.STR = this.STR;
		clone.target = this.target;
		clone.x = this.x;
		clone.y = this.y;
		clone.z = this.z;
		
		return clone;
	}
}
